﻿using DataProcess.Range;
using DataProcess.Sort;
using System;
using System.Collections.Generic;
using static DataProcess.Mathematics.NumberCase;
namespace DataProcess.Special
{

    /// <summary>
    /// 伽罗瓦域多项式
    /// </summary>
    public class GPolynomial
    {
        private List<GPolynomialItem> GaloisGPolynomialitems = new List<GPolynomialItem>();

        public void setX(int x)
        {
            foreach (GPolynomialItem item in GaloisGPolynomialitems)
            {
                item.X = x;
            }
        }
        public double GetValue()
        {
            double res = 0;
            foreach (GPolynomialItem item in GaloisGPolynomialitems)
            {
                res += (double)item;
            }

            return res;
        }
        public override string ToString()
        {
            string res = "";
            if (GaloisGPolynomialitems.Count == 0)
            {
                return "0";
            }

            foreach (GPolynomialItem item in GaloisGPolynomialitems)
            {
                if ((int)item.m >= 0)
                {
                    res += string.Format("+{0}", item);
                }
                else
                {
                    res += string.Format("{0}", item);
                }
            }
            return res;
        }
        public GPolynomialItem[] GetAllGaloisGPolynomialItems()
        {
            return GaloisGPolynomialitems.ToArray();
        }
        public void SortByP()
        {
            DataTool data = new DataTool();
            GPolynomialItem[] arr = GaloisGPolynomialitems.ToArray();
            data.CustomQuickSort<GPolynomialItem>(arr, new sortClass(), 0, GaloisGPolynomialitems.Count - 1);
            GaloisGPolynomialitems = new List<GPolynomialItem>(arr);
        }

        private class sortClass : DataTool.ISortCondition
        {
            public bool SortConditionAfter(object after, object key)
            {
                return ((GPolynomialItem)after).p >= ((GPolynomialItem)key).p;
            }

            public bool SortConditionBefore(object before, object key)
            {
                return ((GPolynomialItem)before).p <= ((GPolynomialItem)key).p;
            }
        }
        public GPolynomial Simplify()
        {
            GPolynomial GPolynomial = new GPolynomial();
            foreach (int p in AlreadyHasP())
            {

                GPolynomialItem[] samePitems = GetItemByP(p);
                if (samePitems.Length == 0)
                {
                    continue;
                }
                else if (samePitems.Length == 1)
                {
                    if ((int)samePitems[0].m != 0)
                    {
                        GPolynomial.Add(samePitems);
                    }
                }
                else
                {
                    GPolynomialItem stand = samePitems[0];
                    for (int i = 1; i < samePitems.Length; i++)
                    {
                        stand += samePitems[i];
                    }
                    if ((int)stand.m != 0)
                    {
                        GPolynomial.Add(stand);
                    }
                }
            }
            return GPolynomial;
        }
        public void Remove(GPolynomialItem item)
        {
            GaloisGPolynomialitems.Remove(item);
        }
        public void Remove(int start, int length)
        {
            GaloisGPolynomialitems.RemoveRange(start, length);
        }
        public void Add(params GPolynomialItem[] items)
        {
            GaloisGPolynomialitems.AddRange(items);
        }
        public double MaxP
        {
            get
            {
                if (GaloisGPolynomialitems.Count == 0)
                {
                    return 0;
                }

                int maxp = GaloisGPolynomialitems[0].p;
                for (int i = 1; i < GaloisGPolynomialitems.Count; i++)
                {
                    if (GaloisGPolynomialitems[i].p > maxp)
                    {
                        maxp = GaloisGPolynomialitems[i].p;
                    }
                }
                return maxp;
            }
        }
        public double MinP
        {
            get
            {
                if (GaloisGPolynomialitems.Count == 0)
                {
                    return 0;
                }

                int minp = GaloisGPolynomialitems[0].p;
                for (int i = 1; i < Count; i++)
                {
                    if (GaloisGPolynomialitems[i].p < minp)
                    {
                        minp = GaloisGPolynomialitems[i].p;
                    }
                }
                return minp;
            }
        }
        public GPolynomialItem[] GetItemByP(double p)
        {
            List<GPolynomialItem> items = new List<GPolynomialItem>();
            for (int i = 0; i < Count; i++)
            {
                if (GaloisGPolynomialitems[i].p == p)
                {
                    items.Add(GaloisGPolynomialitems[i]);
                }
            }

            return items.ToArray();
        }
        public double[] GetAllItemsP()
        {
            double[] ps = new double[Count];
            for (int i = 0; i < Count; i++)
            {
                ps[i] = GaloisGPolynomialitems[i].p;
            }

            return ps;
        }
        public double[] AlreadyHasP()
        {
            List<double> res = new List<double>();
            for (int i = 0; i < Count; i++)
            {
                if (!res.Contains(GaloisGPolynomialitems[i].p))
                {
                    res.Add(GaloisGPolynomialitems[i].p);
                }
            }
            return res.ToArray();
        }
        public GPolynomialItem this[int index]
        {
            get => GaloisGPolynomialitems[index];
            set => GaloisGPolynomialitems[index] = value;
        }
        public int Count => GaloisGPolynomialitems.Count;
        public GPolynomial(params GPolynomialItem[] items)
        {
            GaloisGPolynomialitems = new List<GPolynomialItem>(items);
        }

        public static GPolynomial operator +(GPolynomial a, GPolynomial b)
        {
            GPolynomial sima = a.Simplify();
            GPolynomial simb = b.Simplify();
            GPolynomial GPolynomial = new GPolynomial(sima.GetAllGaloisGPolynomialItems());
            GPolynomial.Add(simb.GetAllGaloisGPolynomialItems());
            return GPolynomial.Simplify();

        }
        public static GPolynomial operator -(GPolynomial a, GPolynomial b)
        {
            GPolynomial sima = a.Simplify();
            GPolynomial simb = b.Simplify();
            GPolynomial GPolynomial = new GPolynomial(sima.GetAllGaloisGPolynomialItems());
            GPolynomial.Add(simb.GetAllGaloisGPolynomialItems());
            return GPolynomial.Simplify();

        }
        public static GPolynomial operator *(GPolynomial a, GPolynomial b)
        {
            GPolynomial GPolynomial = new GPolynomial();
            for (int i = 0; i < a.Count; i++)
            {
                for (int j = 0; j < b.Count; j++)
                {
                    GPolynomial.Add(a[i] * b[j]);
                }

            }
            return GPolynomial.Simplify();
        }
        public static GPolynomial operator /(GPolynomial a, GPolynomial b)
        {
            GPolynomial ta = new GPolynomial(a.GetAllGaloisGPolynomialItems());
            GPolynomial tb = new GPolynomial(b.GetAllGaloisGPolynomialItems());
            GPolynomial sarry = new GPolynomial();
            int max = (int)a.MaxP;
            GPolynomialItem[] bitem = tb.GetItemByP(tb.MaxP);
            while (true)
            {
                GPolynomialItem[] aitem = ta.GetItemByP(max--);
                if (aitem.Length == 0)
                {
                    continue;
                }

                GPolynomialItem s = aitem[0] / bitem[0];
                sarry.Add(s);
                GPolynomial cutitem = new GPolynomial(s) * tb;
                ta -= cutitem;
                if (s.p < 0)
                {
                    sarry.Remove(s);
                    break;
                }
                if (s.p == 0)
                {
                    break;
                }

                if (ta.ToString().Equals("0"))
                {
                    return sarry;
                }
            }
            return sarry;
        }
        public static GPolynomial operator %(GPolynomial a, GPolynomial b)
        {
            GPolynomial ta = new GPolynomial(a.GetAllGaloisGPolynomialItems());
            GPolynomial tb = new GPolynomial(b.GetAllGaloisGPolynomialItems());
            int max = (int)a.MaxP;
            GPolynomialItem[] bitem = tb.GetItemByP(tb.MaxP);
            while (true)
            {
                GPolynomialItem[] aitem = ta.GetItemByP(max--);
                if (aitem.Length == 0)
                {
                    continue;
                }

                GPolynomialItem s = aitem[0] / bitem[0];
                GPolynomial cutitem = new GPolynomial(s) * tb;
                ta -= cutitem;
                if (s.p < 0)
                {
                    ta += cutitem;
                    break;
                }
                if (s.p == 0)
                {
                    break;
                }

                if (ta.ToString().Equals("0"))
                {
                    return ta;
                }
            }
            return ta;
        }
    }
    /// <summary>
    /// 伽罗瓦域多项式单项
    /// </summary>
    public class GPolynomialItem
    {
        public override string ToString()
        {
            if (p != 0 && (int)m != 0)
            {
                return string.Format("{0}X^{1}", m, p);
            }
            else if ((int)m == 0)
            {
                return "0";
            }
            else
            {
                return m.ToString();
            }
        }
        public static GPolynomialItem operator +(GPolynomialItem a, GPolynomialItem b)
        {
            if (a.p != b.p)
            {
                throw new Exception("指数幂不同无法运算加减");
            }
            else
            {
                return new GPolynomialItem(a.m + b.m, a.p);
            }
        }
        public static GPolynomialItem operator -(GPolynomialItem a, GPolynomialItem b)
        {
            if (a.p != b.p)
            {
                throw new Exception("指数幂不同无法运算加减");
            }
            else
            {
                int m = (int)(a.m - b.m);
                return new GPolynomialItem(m, (int)a.m);
            }
        }
        public static GPolynomialItem operator *(GPolynomialItem a, GPolynomialItem b)
        {
            GaloisField mx = (a.m * b.m);
            GaloisField m = new GaloisField(4) { Value = (int)mx };
            return new GPolynomialItem(m, a.p + b.p);
        }
        public static GPolynomialItem operator /(GPolynomialItem a, GPolynomialItem b)
        {
            return new GPolynomialItem(new GaloisField(4) { Value = (int)a.m / (int)b.m }, a.p - b.p);
        }
        /// <summary>
        /// 指数幂
        /// </summary>
        public int p
        {
            get;
            set;
        }
        /// <summary>
        /// 系数
        /// </summary>
        public GaloisField m
        {
            get;
            set;
        }
        /// <summary>
        /// 未知数X
        /// </summary>
        public int? X
        {
            get;
            set;
        }
        public GPolynomialItem()
        {
        }
        /// <summary>
        /// 多项式
        /// </summary>
        /// <param name="m">多项式的指数幂</param>
        /// <param name="p">多项式的系数</param>
        public GPolynomialItem(GaloisField m, int p)
        {
            this.p = p;
            this.m = m;
        }
        public static implicit operator GPolynomial(GPolynomialItem item)
        {
            return new GPolynomial(item);
        }
        public static implicit operator GPolynomialItem(int m)
        {
            return new GPolynomialItem(m, 0);
        }
        public static implicit operator double(GPolynomialItem d)
        {
            if (d.X == null)
            {
                throw new Exception("多项式X的值不能为空");
            }

            return (int)d.m * (Math.Pow((int)d.X, d.p));
        }
    }

    /// <summary>
    /// 伽罗瓦域
    /// </summary>
    public class GaloisField
    {
        private int _value;
        /// <summary>
        /// 默认P值，当从int转换时有效
        /// </summary>
        public static int? DefaultP
        {
            set;
            get;
        }

        private int max;

        private int[] Narray;

        /// <summary>
        /// 值
        /// </summary>
        public int Value
        {
            get => _value;
            set
            {
                if (value > Max)
                {
                    throw new Exception("值不能大于有限界");
                }

                _value = value;
            }
        }
        /// <summary>
        /// 本原多项式的10进制数
        /// </summary>
        public int N
        {
            get;
            private set;
        }

        private int p;

        /// <summary>
        /// 指数幂
        /// </summary>
        public int P
        {
            get => p;
            set
            {
                Narray = GetN();

                if (value >= 0 && value < Narray.Length)
                {
                    max = (int)Math.Pow(2, value);
                    p = value;
                    N = Narray[value];
                }
                else
                {
                    throw new Exception("该值将设定限界，必须>=0且<" + Narray.Length.ToString());
                }
            }
        }
        /// <summary>
        /// 域中最大值
        /// </summary>
        public int Max
        {
            get => max;
            set => max = value;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="maxlimtP">2的指数幂，即设定该类中的最大值为2的maxlimtP次方</param>
        public GaloisField(int maxlimtP)
        {
            P = maxlimtP;
        }

        /// <summary>
        /// 提供本原多项式
        /// </summary>
        /// <returns></returns>
        protected virtual int[] GetN()
        {
            return new int[]
            {0,1,
(int)ExchangeToTen("7",8),
(int)ExchangeToTen("13",8),
(int)ExchangeToTen("23",8),
(int)ExchangeToTen("45",8),
(int)ExchangeToTen("103",8),
(int)ExchangeToTen("211",8),
(int)ExchangeToTen("435",8),
(int)ExchangeToTen("1021",8),
(int)ExchangeToTen("2011",8),

            };
        }

        public override string ToString()
        {
            return _value.ToString();
        }

        public static GaloisField operator +(GaloisField a, GaloisField b)
        {

            int maxlimtP = SameP(a, b);
            return new GaloisField(maxlimtP)
            {
                _value = (a._value ^ b._value),
            };
        }

        public static GaloisField operator +(GaloisField a, int t)
        {
            GaloisField galoisField = t;
            int num3 = galoisField.P = (a.P = BaseMathTool.getMax(new int[2]
            {
                a.P,
                galoisField.P
            }));
            return new GaloisField(a.P)
            {
                _value = (a._value ^ (int)galoisField),
            };
        }

        public static GaloisField operator *(GaloisField a, int t)
        {
            GaloisField galoisField = t;
            int num3 = BaseMathTool.getMax(new int[] { galoisField.P, a.P });
            a.P = num3;
            galoisField.p = num3;
            if (a._value * t >= a.Max)
            {
                return new GaloisField(a.P)
                {
                    _value = Mod2Math.Mod2Mod(Mod2Math.Mod2Multy(a.Value, (int)galoisField), a.N),
                };
            }

            return new GaloisField(a.P)
            {
                _value = a._value * t,
            };
        }

        private static int SameP(GaloisField a, GaloisField b)
        {

            int maxlimtP = BaseMathTool.getMax(new int[] { a.P, b.P });
            return maxlimtP;
        }
        public static GaloisField operator *(GaloisField a, GaloisField b)
        {
            int num3 = BaseMathTool.getMax(new int[] { b.P, a.P });
            a.P = num3;
            b.p = num3;
            if (a._value * b.Value >= a.Max)
            {
                return new GaloisField(a.P)
                {
                    _value = Mod2Math.Mod2Mod(Mod2Math.Mod2Multy(a.Value, b.Value), a.N),
                };
            }

            return new GaloisField(a.P)
            {
                _value = a._value * b.Value,
            };
        }

        public static GaloisField operator -(GaloisField a, GaloisField b)
        {
            int maxlimtP = SameP(a, b);
            return new GaloisField(maxlimtP)
            {
                _value = (a._value ^ b._value),
                N = a.N
            };
        }

        public static GaloisField operator -(GaloisField a, int t)
        {
            GaloisField galoisField = t;
            int num3 = galoisField.p = (a.P = BaseMathTool.getMax(new int[2]
            {
                a.P,
                galoisField.P
            }));
            return new GaloisField(a.P)
            {
                _value = (a._value ^ (int)galoisField),
                N = a.N
            };
        }

        public static explicit operator int(GaloisField d)
        {
            return d._value;
        }

        public static implicit operator GaloisField(int d)
        {
            double num = 0.0;
            int num2 = 0;
            while (d > num)
            {
                num = Math.Pow(2.0, ++num2);
            }
            if (GaloisField.DefaultP != null && GaloisField.DefaultP > num2)
            {
                num2 = (int)DefaultP;
            }
            return new GaloisField(num2)
            {
                Value = d
            };
        }
    }
    /// <summary>
    /// 多项式
    /// </summary>
    public class Polynomial
    {
        private List<PolynomialItem> Polynomialitems = new List<PolynomialItem>();
        public override string ToString()
        {
            string res = "";
            if (Polynomialitems.Count == 0)
            {
                return "0";
            }

            foreach (PolynomialItem item in Polynomialitems)
            {
                if (item.m >= 0)
                {
                    res += string.Format("+{0}", item);
                }
                else
                {
                    res += string.Format("{0}", item);
                }
            }
            return res;
        }
        /// <summary>
        /// 获取当前的多项式的所有单个mX^p形式的单项
        /// </summary>
        /// <returns></returns>
        public PolynomialItem[] GetAllPolynomialItems()
        {
            return Polynomialitems.ToArray();
        }
        /// <summary>
        /// 将多项式按指数幂大小进行排序
        /// </summary>
        public void SortByP()
        {
            DataProcess.Sort.DataTool data = new DataProcess.Sort.DataTool();
            PolynomialItem[] arr = Polynomialitems.ToArray();
            data.CustomQuickSort<PolynomialItem>(arr, new sortClass(), 0, Polynomialitems.Count - 1);
            Polynomialitems = new List<PolynomialItem>(arr);
        }

        private class sortClass : DataProcess.Sort.DataTool.ISortCondition
        {
            public bool SortConditionAfter(object after, object key)
            {
                return ((PolynomialItem)after).p >= ((PolynomialItem)key).p;
            }

            public bool SortConditionBefore(object before, object key)
            {
                return ((PolynomialItem)before).p <= ((PolynomialItem)key).p;
            }
        }
        /// <summary>
        /// 对多项式进行简化
        /// </summary>
        /// <returns></returns>
        public Polynomial Simplify()
        {
            Polynomial polynomial = new Polynomial();
            foreach (int p in AlreadyHasP())
            {

                PolynomialItem[] samePitems = GetItemByP(p);
                if (samePitems.Length == 0)
                {
                    continue;
                }
                else if (samePitems.Length == 1)
                {
                    if (samePitems[0].m != 0)
                    {
                        polynomial.Add(samePitems);
                    }
                }
                else
                {
                    PolynomialItem stand = samePitems[0];
                    for (int i = 1; i < samePitems.Length; i++)
                    {
                        stand += samePitems[i];
                    }
                    if (stand.m != 0)
                    {
                        polynomial.Add(stand);
                    }
                }
            }
            return polynomial;
        }

        /// <summary>
        /// 移除某一项单项
        /// </summary>
        /// <param name="item">指定单项</param>
        public void Remove(PolynomialItem item)
        {
            Polynomialitems.Remove(item);
        }
        /// <summary>
        /// 移除多项式中的start开始后的length项
        /// </summary>
        /// <param name="start"></param>
        /// <param name="length"></param>
        public void Remove(int start, int length)
        {
            Polynomialitems.RemoveRange(start, length);
        }
        /// <summary>
        /// 向多项式中添加若干个单项
        /// </summary>
        /// <param name="items"></param>
        public void Add(params PolynomialItem[] items)
        {
            Polynomialitems.AddRange(items);
        }
        /// <summary>
        /// 当前多项式中最大指数幂
        /// </summary>
        public double MaxP
        {
            get
            {
                int maxp = Polynomialitems[0].p;
                for (int i = 1; i < Polynomialitems.Count; i++)
                {
                    if (Polynomialitems[i].p > maxp)
                    {
                        maxp = Polynomialitems[i].p;
                    }
                }
                return maxp;
            }
        }
        /// <summary>
        /// 当前多项式中最小指数幂
        /// </summary>
        public double MinP
        {
            get
            {
                int minp = Polynomialitems[0].p;
                for (int i = 1; i < Count; i++)
                {
                    if (Polynomialitems[i].p < minp)
                    {
                        minp = Polynomialitems[i].p;
                    }
                }
                return minp;
            }
        }
        /// <summary>
        /// 获取所有指定指数幂的单项式
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public PolynomialItem[] GetItemByP(double p)
        {
            List<PolynomialItem> items = new List<PolynomialItem>();
            for (int i = 0; i < Count; i++)
            {
                if (Polynomialitems[i].p == p)
                {
                    items.Add(Polynomialitems[i]);
                }
            }

            return items.ToArray();
        }

        /// <summary>
        /// 获取每一项单项式的指数幂，包括重复的
        /// </summary>
        /// <returns></returns>
        public double[] GetAllItemsP()
        {
            double[] ps = new double[Count];
            for (int i = 0; i < Count; i++)
            {
                ps[i] = Polynomialitems[i].p;
            }

            return ps;
        }
        /// <summary>
        ///  获取每一项单项式的指数幂，不括重复的
        /// </summary>
        /// <returns></returns>
        public double[] AlreadyHasP()
        {
            List<double> res = new List<double>();
            for (int i = 0; i < Count; i++)
            {
                if (!res.Contains(Polynomialitems[i].p))
                {
                    res.Add(Polynomialitems[i].p);
                }
            }
            return res.ToArray();
        }
        public PolynomialItem this[int index]
        {
            get => Polynomialitems[index];
            set => Polynomialitems[index] = value;
        }
        /// <summary>
        /// 当前多项式单项的数量
        /// </summary>
        public int Count => Polynomialitems.Count;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="items">添加进多项式的单项</param>
        public Polynomial(params PolynomialItem[] items)
        {
            Polynomialitems = new List<PolynomialItem>(items);
        }

        public static Polynomial operator +(Polynomial a, Polynomial b)
        {
            Polynomial sima = a.Simplify();
            Polynomial simb = b.Simplify();
            Polynomial polynomial = new Polynomial(sima.GetAllPolynomialItems());
            polynomial.Add(simb.GetAllPolynomialItems());
            return polynomial.Simplify();

        }
        public static Polynomial operator -(Polynomial a, Polynomial b)
        {
            Polynomial sima = a.Simplify();
            Polynomial simb = b.Simplify();
            foreach (PolynomialItem item in simb.GetAllPolynomialItems())
            {
                item.m = -item.m;
            }
            Polynomial polynomial = new Polynomial(sima.GetAllPolynomialItems());
            polynomial.Add(simb.GetAllPolynomialItems());
            return polynomial.Simplify();

        }

        public static Polynomial operator ^(Polynomial a, Polynomial b)
        {
            Polynomial res = new Polynomial();
            Polynomial polynomial = new Polynomial(a.GetAllPolynomialItems());
            polynomial.Add(b.GetAllPolynomialItems());
            foreach (int p in polynomial.AlreadyHasP())
            {

                PolynomialItem[] samePitems = polynomial.GetItemByP(p);
                if (samePitems.Length == 0)
                {
                    continue;
                }
                else if (samePitems.Length == 1)
                {
                    if (samePitems[0].m != 0)
                    {
                        res.Add(samePitems);
                    }
                }
                else
                {
                    PolynomialItem stand = samePitems[0];
                    for (int i = 1; i < samePitems.Length; i++)
                    {
                        stand ^= samePitems[i];
                    }
                    if (stand.m != 0)
                    {
                        res.Add(stand);
                    }
                }
            }
            return res;

        }
        public static Polynomial operator *(Polynomial a, Polynomial b)
        {
            Polynomial polynomial = new Polynomial();
            for (int i = 0; i < a.Count; i++)
            {
                for (int j = 0; j < b.Count; j++)
                {
                    polynomial.Add(a[i] * b[j]);
                }

            }
            return polynomial.Simplify();
        }
        public static Polynomial operator /(Polynomial a, Polynomial b)
        {
            Polynomial ta = new Polynomial(a.GetAllPolynomialItems()).Simplify();
            Polynomial tb = new Polynomial(b.GetAllPolynomialItems()).Simplify();
            Polynomial sarry = new Polynomial();
            int max = (int)a.MaxP;
            PolynomialItem[] bitem = tb.GetItemByP(tb.MaxP);
            while (true)
            {
                PolynomialItem[] aitem = ta.GetItemByP(max--);
                if (aitem.Length == 0)
                {
                    continue;
                }

                PolynomialItem s = aitem[0] / bitem[0];
                sarry.Add(s);
                Polynomial cutitem = new Polynomial(s) * tb;
                ta -= cutitem;
                if (s.p < 0)
                {
                    sarry.Remove(s);
                    break;
                }
                if (s.p == 0)
                {
                    break;
                }

                if (ta.ToString().Equals("0"))
                {
                    return sarry;
                }
            }
            return sarry;
        }
        public static Polynomial operator %(Polynomial a, Polynomial b)
        {
            Polynomial ta = new Polynomial(a.GetAllPolynomialItems()).Simplify();
            Polynomial tb = new Polynomial(b.GetAllPolynomialItems()).Simplify();
            int max = (int)a.MaxP;
            PolynomialItem[] bitem = tb.GetItemByP(tb.MaxP);
            while (max != 0)
            {
                PolynomialItem[] aitem = ta.GetItemByP(max--);
                if (aitem.Length == 0)
                {
                    continue;
                }

                PolynomialItem s = aitem[0] / bitem[0];
                Polynomial cutitem = new Polynomial(s) * tb;
                ta -= cutitem;
                if (s.p < 0)
                {
                    ta += cutitem;
                    break;
                }
                if (s.p == 0)
                {
                    break;
                }

                if (ta.ToString().Equals("0"))
                {
                    break;
                }
            }
            return ta;
        }

    }
    /// <summary>
    /// 单个多项式单元类
    /// </summary>
    public class PolynomialItem
    {
        public override string ToString()
        {
            if (p != 0 && m != 0)
            {
                return string.Format("{0}X^{1}", m, p);
            }
            else if (m == 0)
            {
                return "0";
            }
            else
            {
                return m.ToString();
            }
        }
        public static PolynomialItem operator +(PolynomialItem a, PolynomialItem b)
        {
            if (a.p != b.p)
            {
                throw new Exception("指数幂不同无法运算加减");
            }
            else
            {
                return new PolynomialItem(a.m + b.m, a.p);
            }
        }
        public static PolynomialItem operator -(PolynomialItem a, PolynomialItem b)
        {
            if (a.p != b.p)
            {
                throw new Exception("指数幂不同无法运算加减");
            }
            else
            {
                return new PolynomialItem(a.m - b.m, a.m);
            }
        }
        public static PolynomialItem operator *(PolynomialItem a, PolynomialItem b)
        {
            return new PolynomialItem(a.m * b.m, a.p + b.p);
        }
        public static PolynomialItem operator /(PolynomialItem a, PolynomialItem b)
        {
            return new PolynomialItem(a.m / b.m, a.p - b.p);
        }
        public static PolynomialItem operator ^(PolynomialItem a, PolynomialItem b)
        {
            if (a.p != b.p)
            {
                throw new Exception("指数幂不同无法进行异或运算");
            }
            else
            {
                return new PolynomialItem(a.m ^ b.m, a.p);
            }
        }
        /// <summary>
        /// 指数幂
        /// </summary>
        public int p
        {
            get;
            set;
        }
        /// <summary>
        /// 系数
        /// </summary>
        public int m
        {
            get;
            set;
        }
        /// <summary>
        /// 未知数X
        /// </summary>
        public int? X
        {
            get;
            set;
        }
        public PolynomialItem()
        {
        }
        /// <summary>
        /// 多项式
        /// </summary>
        /// <param name="m">多项式的指数幂</param>
        /// <param name="p">多项式的系数</param>
        public PolynomialItem(int m, int p)
        {
            this.p = p;
            this.m = m;
        }
        public static implicit operator Polynomial(PolynomialItem item)
        {
            return new Polynomial(item);
        }
        public static implicit operator PolynomialItem(int m)
        {
            return new PolynomialItem(m, 0);
        }
        public static implicit operator double(PolynomialItem d)
        {
            if (d.X == null)
            {
                throw new Exception("多项式X的值不能为空");
            }

            return d.m * (Math.Pow((int)d.X, d.p));
        }
    }


}
